﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using System;
using System.Threading.Tasks;
using VisionCloud.Api.Auth;
using VisionCloud.Domain.Common;
using VisionCloud.Domain.DtoModel.Sys;
using VisionCloud.Domain.Filters;
using VisionCloud.Domain.ModelAttribute;
using VisionCloud.Service.Sys;
using VisionCloud.Utility.Security;

namespace VisionCloud.Api.Controllers.Sys
{
    /// <summary>
    /// 认证控制器
    /// </summary>
    [SystemModule("认证控制器")]
    [ApiAuthorize(PolicyEnum.RequireRolePermission)]
    [ApiVersion("1.0")]
    [Route("api/sys/[controller]/[Action]")]
    [ApiExplorerSettings(GroupName = "认证控制器")]
    public class AuthController : AuthBaseControlller
    {
        /// <summary>
        /// 用户退出登录
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [ApiExplorerSettings(IgnoreApi = true)]
        public async Task<ApiResult> Logout()
        {
            return await TryCatchAsync(UserService.Logout(TokenModel, AuthCore.GetExpires(), () =>
            {
                this.DeleteCookies(CookiesHelper.CookiesName);
            }));
        }

        /// <summary>
        /// 测试surface和云端通讯的验证
        /// </summary>
        /// <returns></returns>
        [ApiAuthorize(PolicyEnum.RequireCheckUserDevice)]
        [HttpPost]
        [ApiExplorerSettings(IgnoreApi = true)]
        public async Task<ApiResult> TestDeviceCheck()
        {
            return await TryCatchAsync(Task.Run(async () =>
            {
                var token = "test";
                return new JwtDto() { Token = token };
            }));
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="userChangeDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> GetUserChangeInfo(UserChangeDto userChangeDto)
        {
            var result = await TryCatchAsync(UserService.GetUserChangeInfo(userChangeDto));
            return result;
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="modelDto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        public async Task<ApiResult> AuthLogin(SysUserLoginDto modelDto)
        {
            SysUserDto sysUserDto = new SysUserDto();
            sysUserDto.Email = modelDto.Email;
            sysUserDto.Password = modelDto.Password;
            sysUserDto.TokenType = modelDto.TokenType;
            return await TryCatchAsync(GetToken(sysUserDto));
        }

        [AllowAnonymous]
        [HttpPost]
        public async Task<ApiResult> GetTokenId(SysUserLoginDto modelDto)
        {
            SysUserDto sysUserDto = new SysUserDto();
            sysUserDto.Email = modelDto.Email;
            sysUserDto.Password = modelDto.Password;
            sysUserDto.TokenType = TokenTypeEnum.SurfaceApp;
            var result = await TryCatchAsync(GetToken(sysUserDto));
            if (result.Code == AjaxCode.Error)
            {
                return result;
            }

            if (result.Result.ToString().Contains("修改密码"))
            {
                result.Code = AjaxCode.ChangePassword;
                result.Message = localizer["YB0022"].Value;
                return result;
            }
            else
            {
                Guid id = Guid.NewGuid();
                Cached.Set(id.ToString(), result.Result.ToString(), TimeSpan.FromSeconds(180));
                result.Result = id;
                return result;
            }
        }

        /// <summary>
        /// 平板端自动授权登录云端
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        public ApiResult GetTokenByID(GetTokenDto dto)
        {
            try
            {
                var token = Cached.Get<string>(dto.Id.ToString());
                if (string.IsNullOrEmpty(token))
                {
                    throw new OperationException(localizer["YB0023"].Value);
                }
                else
                {
                    this.SetCookiet(CookiesHelper.CookiesName, token);
                    return new ApiResult() { Code = AjaxCode.Success, Result = token };
                }
            }
            catch (Exception ex)
            {
                return ApiResult.Error(ex.Message);//new ApiResult(Domain.Common.AjaxCode.Error, ex.Message);
            }
        }

        /// <summary>
        ///  测量服务：客户API-用户明文登录
        /// </summary>
        /// <param name="modelDto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost, SwaggerOperation(Tags = new[] { "测量服务" })]
        public async Task<ApiResult> AuthLoginClient2(SysUserLoginDto modelDto)
        {
            return await TryCatchAsync(Task.Run(async () =>
            {
                if (string.IsNullOrWhiteSpace(modelDto.Email))
                {
                    throw new OperationException(localizer["YB0025"].Value);
                }

                if (string.IsNullOrWhiteSpace(modelDto.Password))
                {
                    throw new OperationException(localizer["YB0026"].Value);
                }

                SysUserDto model = new SysUserDto();
                RSACryptoService rsa = new RSACryptoService(RSACryptoService.DefaultPrivateKey, RSACryptoService.DefaultPublicKey);
                model.Email = rsa.Encrypt(modelDto.Email);
                model.Password = rsa.Encrypt(modelDto.Password);
                model.TokenType = modelDto.TokenType;
                return await TryCatchAsync(GetToken(model));
            }));
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="modelDto"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        public async Task<ApiResult> AuthLoginSurface(DeviceLoginDto modelDto)
        {
            SysUserDto model = new SysUserDto();
            try
            {
                RSACryptoService rsa = new RSACryptoService(RSACryptoService.DefaultPrivateKey, RSACryptoService.DefaultPublicKey);
                model.YunUserGuid = new Guid(rsa.Decrypt(modelDto.YunUserGuid));
                string drogNum = rsa.Decrypt(modelDto.DogNum);
                return await TryCatchAsync(GetTokenWithSurface(model, drogNum, true));
            }
            catch (Exception ex)
            {
                return new ApiResult() { Code = AjaxCode.Error, Message = ex.Message.ToString() };
            }
        }

        public class GetTokenDto
        {
            [GuidRequired] public Guid Id { get; set; }
        }
    }
}